package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.OmcExpenseTypeMapper;
import com.csun.cmny.provider.dao.OmcExpenseTypeModelCodeMapper;
import com.csun.cmny.provider.exceptions.OmcBizException;
import com.csun.cmny.provider.model.domain.*;
import com.csun.cmny.provider.model.dto.ExpenseTypeDto;
import com.csun.cmny.provider.model.dto.expenseItem.ExpenseItemSelectDto;
import com.csun.cmny.provider.model.vo.ExpenseTypeAllVo;
import com.csun.cmny.provider.model.vo.ExpenseTypeVo;
import com.csun.cmny.provider.model.vo.expenItem.ExpenseItemTheVo;
import com.csun.cmny.provider.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Slf4j
@Transactional
public class OmcExpenseTypeServiceImpl extends BaseService<OmcExpenseType> implements OmcExpenseTypeService {

    @Resource
    private OmcExpenseTypeMapper omcExpenseTypeMapper;

    @Resource
    private OmcExpenseTypeModelCodeMapper omcExpenseTypeModelCodeMapper;
    @Resource
    private OmcExpenseItemService omcExpenseItemService;

    @Resource
    private OmcOldManTypeIetypeService omcOldManTypeIetypeService;

    @Resource
    private OmcOldmanExpenseItemService omcOldmanExpenseItemService;

    @Resource
    private OmcUserTypeService omcUserTypeService;

    @Resource
    private OmcExpenseTypeModelCodeService omcExpenseTypeModelCodeService;

    @Override
    public Integer saveExpenseType(OmcExpenseType omcExpenseType, LoginAuthDto loginAuthDto) {

        omcExpenseType.setUpdateInfo(loginAuthDto);
        
        //放入操作人员信息
        //如果没有传groupId,放入操作员groupId
        if(omcExpenseType.getGroupId() == null || omcExpenseType.getGroupId() == 0){
            omcExpenseType.setGroupId(loginAuthDto.getGroupId());
        }

        if(omcExpenseType.getName() != null){
            //同名校验
            if(!checkName(omcExpenseType)){
                throw new OmcBizException(ErrorCodeEnum.OMC10037010);
            }
        }
        //判断是修改或添加
        if(omcExpenseType.isNew()){
            int n = omcExpenseTypeMapper.insertSelective(omcExpenseType);
            if(n > 0){
                //查询机构中的人员类别
                OmcUserType userType = new OmcUserType();
                userType.setGroupId(omcExpenseType.getGroupId());
                List<OmcUserType> userTypes = omcUserTypeService.select(userType);
                List<OmcOldManTypeIetype> oldManTypeIetypeList = new LinkedList<>();
                Set<Long> userTypeIdList = userTypes.stream().map(u->u.getId()).collect(Collectors.toSet());

                //初始化该费用类别的人员减免比例 设置为0
                for(Long userTypeId : userTypeIdList){
                    OmcOldManTypeIetype oldManTypeIetype = new OmcOldManTypeIetype();
                    oldManTypeIetype.setUpdateInfo(loginAuthDto);
                    oldManTypeIetype.setItemId(omcExpenseType.getId());
                    oldManTypeIetype.setGroupId(omcExpenseType.getGroupId());
                    oldManTypeIetype.setUserTypeId(userTypeId);
                    oldManTypeIetype.setPrecent(0);
                    oldManTypeIetypeList.add(oldManTypeIetype);
                }
                if(oldManTypeIetypeList.size() > 0){
                    //绑定默认减免比例
                    int ret = omcOldManTypeIetypeService.batchSave(oldManTypeIetypeList);
                }
            }
            return n;
        }else{
            OmcExpenseType expenseType = selectByKey(omcExpenseType.getId());
            if(expenseType.getCode() != 0){
                omcExpenseType.setName(expenseType.getName());
            }
            //修改名字前需要校验该类别是否使用过，如果使用过，则不能修改
            if(omcExpenseType.getName() != null){
                OmcOldmanExpenseItem oldmanExpenseItem = new OmcOldmanExpenseItem();
                oldmanExpenseItem.setExpenseTypeId(omcExpenseType.getId());
                int hasUsed = omcOldmanExpenseItemService.selectCount(oldmanExpenseItem);
                if(hasUsed > 0){
                    throw new OmcBizException(ErrorCodeEnum.OMC10037045 );
                }
            }
            return omcExpenseTypeMapper.updateByPrimaryKeySelective(omcExpenseType);
        }
    }

    @Override
    public List<ExpenseTypeVo> queryAll(ExpenseTypeDto expenseTypeDto, LoginAuthDto loginAuthDto) {

        //放入操作人员信息
        //如果没有传groupId,放入操作员groupId
        Long groupId = loginAuthDto.getGroupId();
        if(expenseTypeDto.getGroupId() != null){
            groupId = expenseTypeDto.getGroupId();
        }
        //查询全部消费类别
        List<ExpenseTypeVo> expenseTypeVoList = omcExpenseTypeMapper.queryAll(groupId);

        //遍历消费类别，放入消费项目
        for(ExpenseTypeVo vo : expenseTypeVoList){

            //创建查询对象

            ExpenseItemSelectDto expenseItemSelectDto = new ExpenseItemSelectDto();
            expenseItemSelectDto.setExpenseTypeId(vo.getId());
            List<ExpenseItemTheVo>expenseItemList =omcExpenseItemService.selectExpenItem(expenseItemSelectDto);

            //放入消费项目
            if(expenseItemList.size() > 0){
                vo.setExpenseItemList(expenseItemList);
            }
        }
        return expenseTypeVoList;
    }

    @Override
    public List<ExpenseTypeAllVo> queryTypeAll(Long groupId) {

        //查询全部消费类别
        List<ExpenseTypeAllVo> expenseTypeVoList = omcExpenseTypeModelCodeMapper.queryTypeAll(groupId);

        //遍历消费类别，放入消费项目
        for(ExpenseTypeAllVo vo : expenseTypeVoList){

            //创建查询对象
            OmcExpenseItem omcExpenseItemQuery = new OmcExpenseItem();
            omcExpenseItemQuery.setExpenseTypeId(vo.getId().intValue());
            List<OmcExpenseItem> expenseItemList = omcExpenseItemService.select(omcExpenseItemQuery);

            //放入消费项目
            if(expenseItemList.size() > 0){
                vo.setExpenseItemList(expenseItemList);
            }
        }
        return expenseTypeVoList;
    }

    @Override
    public Integer deleteExpenseTypeById(Long expenseTypeId, LoginAuthDto loginAuthDto) {

        OmcOldmanExpenseItem oldmanExpenseItem = new OmcOldmanExpenseItem();
        oldmanExpenseItem.setExpenseTypeId(expenseTypeId);
        int hasUsed = omcOldmanExpenseItemService.selectCount(oldmanExpenseItem);
        if(hasUsed > 0){
            throw new OmcBizException(ErrorCodeEnum.OMC10037042);
        }

        //校验是否是床位费或护理费
        OmcExpenseType omcExpenseType = selectByKey(expenseTypeId);
        if(omcExpenseType != null){
            if(omcExpenseType.getCode() == 1 || omcExpenseType.getCode() == 2 || omcExpenseType.getCode() == 3){
                throw new OmcBizException(ErrorCodeEnum.OMC10037009);
            }
        }

        //查询该类别下是否有消费项目，有则不能删除
        OmcExpenseItem omcExpenseItemQuery = new OmcExpenseItem();
        omcExpenseItemQuery.setExpenseTypeId(expenseTypeId.intValue());
        List<OmcExpenseItem> omcExpenseItemList = omcExpenseItemService.select(omcExpenseItemQuery);
        if(omcExpenseItemList.size() > 0){
            throw new OmcBizException(ErrorCodeEnum.OMC10037003);
        }
        //删除人员类别减免
        OmcOldManTypeIetype typeDelete = new OmcOldManTypeIetype();
        typeDelete.setItemId(expenseTypeId);
        int ret = omcOldManTypeIetypeService.delete(typeDelete);

        OmcExpenseTypeModelCode expenseTypeModelCode = new OmcExpenseTypeModelCode();
        expenseTypeModelCode.setExpenseTypeId(expenseTypeId);
        int i = omcExpenseTypeModelCodeService.selectCount(expenseTypeModelCode);
        if(i > 0){
            throw new OmcBizException(ErrorCodeEnum.OMC10037042);
        }

        return deleteByKey(expenseTypeId);
    }

    @Override
    public Integer baseTypeAdd(Long groupId, LoginAuthDto loginAuthDto) {

        if(groupId == null && groupId.equals(0)){
            groupId = loginAuthDto.getGroupId();
        }

        List<OmcExpenseType> typeList = new LinkedList<>();

        OmcExpenseType bedType = new OmcExpenseType();
        bedType.setGroupId(groupId);
        bedType.setUpdateInfo(loginAuthDto);
        bedType.setName("床位费");
        bedType.setCode(1);
        //同名校验
        if(!checkName(bedType)){
            throw new OmcBizException(ErrorCodeEnum.OMC10037002);
        }

        typeList.add(bedType);

        OmcExpenseType careType = new OmcExpenseType();
        careType.setGroupId(groupId);
        careType.setUpdateInfo(loginAuthDto);
        careType.setName("护理费");
        careType.setCode(2);
        //同名校验
        if(!checkName(careType)){
            throw new OmcBizException(ErrorCodeEnum.OMC10037002);
        }
        typeList.add(careType);

        OmcExpenseType cashPeldge = new OmcExpenseType();
        cashPeldge.setGroupId(groupId);
        cashPeldge.setUpdateInfo(loginAuthDto);
        cashPeldge.setName("押金");
        cashPeldge.setCode(3);
        //同名校验
        if(!checkName(cashPeldge)){
            throw new OmcBizException(ErrorCodeEnum.OMC10037002);
        }

        typeList.add(cashPeldge);
        int ret = batchSave(typeList);

        for(OmcExpenseType omcExpenseType : typeList){
            //查询机构中的人员类别
            OmcUserType userType = new OmcUserType();
            userType.setGroupId(loginAuthDto.getGroupId());
            List<OmcUserType> userTypes = omcUserTypeService.select(userType);
            List<OmcOldManTypeIetype> oldManTypeIetypeList = new LinkedList<>();
            Set<Long> userTypeIdList = userTypes.stream().map(u->u.getId()).collect(Collectors.toSet());

            //初始化该费用类别的人员减免比例 设置为0
            for(Long userTypeId : userTypeIdList){
                OmcOldManTypeIetype oldManTypeIetype = new OmcOldManTypeIetype();
                oldManTypeIetype.setItemId(omcExpenseType.getId());
                oldManTypeIetype.setGroupId(omcExpenseType.getGroupId());
                oldManTypeIetype.setUserTypeId(userTypeId);
                oldManTypeIetype.setPrecent(0);
                oldManTypeIetypeList.add(oldManTypeIetype);
            }
            if(oldManTypeIetypeList.size() > 0){
                //绑定默认减免比例
                omcOldManTypeIetypeService.batchSave(oldManTypeIetypeList);
            }
        }

        return ret;
    }

    public boolean checkName(OmcExpenseType omcExpenseType){

        Example example = new Example(OmcExpenseType.class);
        Example.Criteria criteria = example.createCriteria();

        //添加校验条件
        criteria.andEqualTo("name",omcExpenseType.getName());
        criteria.andEqualTo("groupId",omcExpenseType.getGroupId());
        if(omcExpenseType.getId() != null){
            criteria.andNotEqualTo("id",omcExpenseType.getId());
        }
        int result = selectCountByExample(example);
        return result<1;

    }
}
